import { _decorator, Asset, AssetManager, assetManager, Prefab } from 'cc';
import { EventMgr } from './EventMgr';
import { BaseClass } from './BaseClass';

/**
 * 资源加载模块
 * bundle 里面的资源类型是同一种
 */
export class ResMgr extends BaseClass {
    private static _inst: ResMgr;
    public static get inst(): ResMgr {
        if (this._inst == null) {
            this._inst = new ResMgr();
        }

        return this._inst;
    }

    constructor() {
        super()    
    }


    public async Init() {
        // 测试代码
        /*
        assetManager.loadBundle('Scenes',(err,bundle: AssetManager.Bundle)=>{
            if(err){
                console.log('error',err);
                return;
            }

            console.log(bundle);
        })
        */

        // var bundle:AssetManager.Bundle  = await this.IE_LoadBundle('Datas') as AssetManager.Bundle;
        // console.log(bundle);
        // let ass = await this.IE_LoadAllAssetInBundle(bundle,TextAsset);
        // console.log('=======ass========',ass);
        // ass = await this.IE_LoadAssetInBundle(bundle,'fragment',TextAsset);
        // console.log('=======ass1========',ass);

        // var scensBundle = await this.IE_LoadBundle('Scenes') as AssetManager.Bundle;
        // var sceneData = await this.IE_LoadSceneInBundle(scensBundle,'main');
        // console.log('=======ass2========',sceneData);

        // var s1 = await this.IE_LoadBundleAndAllAssets('Datas',TextAsset);
        // // console.log('=======ass3========',s1);
        
        // var s2 = await this.IE_GetScene('Scenes','main');
        // // console.log('=======ass4========',s2);

        // var s3 = await this.IE_GetAsset('Datas','fragment',TextAsset);
        // console.log('=======ass5========',s3);

    }

    /**
     *   异步加载bundle
     */
    public async IE_LoadBundle(bundleName: string) {
        return new Promise((resolve, reject)=>{
            assetManager.loadBundle(bundleName,(err, bundleData)=>{
                if(err){
                    console.log(err);
                    reject(null);
                    return;
                }
                else{
                    resolve(bundleData);
                    return;
                }
            })
        })
    }

    /**
     *加载bundle 里面的所有资源
     * @param bundle 
     * @param assetType 
     * @returns 
     */
    private async IE_LoadAllAssetInBundle(bundle: AssetManager.Bundle, assetType) {
        return new Promise((resolve,reject)=>{
            bundle.loadDir('',assetType,
                (finished: number, total: number, item: null)=>{
                    // 加载进度
                    // atals、spriteFrame、 TextAsset 都是正常的，使用Prefab时候finished、total 不是具体个数， 
                    if(assetType == Prefab ){
                        // console.log("======finished=======",finished,total);
                        EventMgr.inst.Emit('Loading',finished/total);
                    }
                }, 
                (err, infos)=>{
                if(err){
                    reject(err);
                    return;
                }
                else{
                    //加载完毕成功
                    resolve(infos);
                }
            })
        })
    }

    public async IE_LoadAllAssetInBundle2(bundle: AssetManager.Bundle, assetType,path:string) {
        return new Promise((resolve,reject)=>{
            bundle.loadDir(path,assetType,(err, infos)=>{
                if(err){
                    reject(err);
                }
                else{
                    //加载完毕成功
                    resolve(infos);
                }
            })
        })
    }

    /**
     * 加载bundle 里面的单个资源
     * @param bundle 
     * @param assetName 
     * @param assetType 
     * @returns 
     */
    private async IE_LoadAssetInBundle(bundle:AssetManager.Bundle, assetName: string, assetType){
        return new Promise((resolve, reject)=>{
            bundle.load(assetName, assetType,(err, assetData)=>{
                if(err){
                    reject(err);
                    return;
                }
                else{
                    resolve(assetData);
                }
            })
        })
    }

    /**
     * 加载bundle 里面的单个场景资源
     * @param bundle 
     * @param sceneName 
     * @returns 
     */
    private async IE_LoadSceneInBundle(bundle: AssetManager.Bundle, sceneName: string) {
        return new Promise((resolve, reject)=>{
            bundle.loadScene(sceneName,(err,sceneData)=>{
                if(err){
                    reject(err);
                    return;
                }
                else{
                    resolve(sceneData);
                    return;
                }
            });
        })
    }

    /**
     * 加载bundle 里面的所有资源,这个是同一种类型的资源
     * @param bundleName 
     * @param assetType 
     * @returns 
     */
    public async IE_LoadBundleAndAllAssets(bundleName: string, assetType){
        var bundle: AssetManager.Bundle = await this.IE_LoadBundle(bundleName) as AssetManager.Bundle;
        if(bundle === null){
            return null;
        }

        var assetDatas =  await this.IE_LoadAllAssetInBundle(bundle,assetType);
        return assetDatas;
    }

    /**
     * 加载bundle 里面的单个场景资源
     * @param bundleName 
     * @param scenePath 
     * @returns 
     */
    public async IE_GetScene(bundleName: string, scenePath: string){
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        if(bundle === null) {
            bundle = await this.IE_LoadBundle(bundleName) as any;
            if(bundle === null) {
                console.log("bundle load err: " + bundleName);
                return;
            }
        }
        var sceneData = await this.IE_LoadSceneInBundle(bundle, scenePath) as any;
        return sceneData;
    }

    //获取已经加载完毕的资源
    public GetAsset(bundleName: string, assetPath: string, assetType){
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        var assetData = bundle.get(assetPath,assetType);
        return assetData
    }

    /**
     * 获取指定bundle里面的指定资源
     * @param bundleName 
     * @param assetPath 
     * @param assetType 
     * @returns 
     */
    public async IE_GetAsset(bundleName: string, assetPath: string, assetType) {
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        if(bundle === null) {
            bundle = await this.IE_LoadBundle(bundleName) as any;
            if(bundle === null) {
                console.log("bundle load err: " + bundleName);
                return;
            }
        }

        var assetData = bundle.get(assetPath,assetType);
        if(assetData) {
            return assetData;
        }

        assetData = await this.IE_LoadAssetInBundle(bundle, assetPath, assetType) as any;
        return assetData;
    }

    /***
     * 
     */
    public ReleaseAsset(assetData: Asset): void {
        assetManager.releaseAsset(assetData);
    }

    /**
     * 释放bundle 里面的所有资源
     * @param bundleName 
     * @returns 
     */
    public ReleaseAllAssetInBundle(bundleName: string): void {
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        if(bundle === null) {
            return;
        }

         // 释放所有属于 Asset Bundle 的资源
        bundle.releaseAll();
        //移除bundle
        assetManager.removeBundle(bundle);
    } 

    public AetSceneInfo(bundleName: string): void {
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        let res = bundle.getAssetInfo(bundleName);
        console.log(" AetSceneInfo =  ",res)
    }

    /**
     * 获取bundle 下的所有限资源数目
     * @param bundleName 
     * @returns 
     */
    public async  getAllAssetsInBundle(bundleName: string): Promise<Asset[]> {
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        if (!bundle) {
            console.error(`Bundle "${bundleName}" not found.`);
            return [];
        }
    
        // const paths = bundle.getAllAssetPaths();
        const assets: Asset[] = [];
    
        // for (const path of paths) {
        //     const asset = await bundle.load(path);
        //     if (asset) {
        //         assets.push(asset);
        //     }
        // }
    
        return assets;
    }

}


